#include "StdAfx.h"
#include "StringConvert.h"

UINT CStringConvert::m_nDefaultCodePage = CP_THREAD_ACP;

CStringConvert::CStringConvert(LPCSTR lpMultiByteString, UINT nCodePage)
: m_pMultiByteString(lpMultiByteString)
, m_pWideCharString(NULL)
, m_pLargeStringBuffer(NULL)
, m_nCodePage(nCodePage)
{
	memset(m_smallStringBuffer, 0, sizeof(m_smallStringBuffer));
}

CStringConvert::CStringConvert(LPCWSTR lpWideCharString, UINT nCodePage)
: m_pMultiByteString(NULL)
, m_pWideCharString(lpWideCharString)
, m_pLargeStringBuffer(NULL)
, m_nCodePage(nCodePage)
{
	memset(m_smallStringBuffer, 0, sizeof(m_smallStringBuffer));
}


CStringConvert::~CStringConvert(void)
{
	if(m_pLargeStringBuffer != NULL)
	{
		free(m_pLargeStringBuffer);
	}
}

void* CStringConvert::AllocStringBuffer(int nSize)
{
	if(nSize <= sizeof(m_smallStringBuffer))
	{
		return m_smallStringBuffer;
	}
	else
	{
		m_pLargeStringBuffer = calloc(nSize, 1);
		return m_pLargeStringBuffer;
	}
}

CStringConvert::operator LPCSTR()
{
	if(m_pMultiByteString != NULL)
	{
		return m_pMultiByteString;
	}

	if(m_pWideCharString == NULL)
	{
		return NULL;
	}

	int nBytes = WideCharToMultiByte(m_nCodePage, 0, m_pWideCharString, -1, NULL, 0, NULL, NULL);
	LPSTR pStringBuffer = static_cast<LPSTR>(AllocStringBuffer(nBytes));

	WideCharToMultiByte(m_nCodePage, 0, m_pWideCharString, -1, pStringBuffer, nBytes, "$", NULL);

	m_pMultiByteString = pStringBuffer;
	return m_pMultiByteString;
}

CStringConvert::operator LPCWSTR()
{
	if(m_pWideCharString != NULL)
	{
		return m_pWideCharString;
	}

	if(m_pMultiByteString == NULL)
	{
		return NULL;
	}

	int nCharCount = MultiByteToWideChar(m_nCodePage, 0, m_pMultiByteString, -1, NULL, 0);
	int nBytes = nCharCount*sizeof(WCHAR); 
	LPWSTR pStringBuffer = static_cast<LPWSTR>(AllocStringBuffer(nBytes));

	MultiByteToWideChar(m_nCodePage, 0, m_pMultiByteString, -1, pStringBuffer, nCharCount);

	m_pWideCharString = pStringBuffer;
	return m_pWideCharString;
}

UINT CStringConvert::GetDefaultCodePage()
{
	return m_nDefaultCodePage;
}

void CStringConvert::SetDefaultCodePage(UINT nCodePage)
{
	m_nDefaultCodePage = nCodePage;
}
